package org.hawk.gwt.ppc.parser.impl;

import junit.framework.TestCase;

public class SimpleExpressionsTestCase extends TestCase {
	
	public void testDummy() {}
/*
	public void testUnaryOperators() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 0);
		
		assertEquals(7, block.size());
		
		unaryTest(((OperatorExpressionDescriptor)block.get(0)).getRightOperand(), "-", "a");
		unaryTest(((OperatorExpressionDescriptor)block.get(1)).getRightOperand(), "+", "a");
		unaryTest((ExpressionDescriptor)block.get(2), "++", "a");
		unaryTest((ExpressionDescriptor)block.get(3), "--", "a");
		unaryTest(((OperatorExpressionDescriptor)block.get(4)).getRightOperand(), "~", "a");
		unaryTest(((OperatorExpressionDescriptor)block.get(5)).getRightOperand(), "!", "b");
	}
	
	private void unaryTest(ExpressionDescriptor unary, String operator, String var) {
		assertTrue(unary instanceof OperatorExpressionDescriptor);
		
		OperatorExpressionDescriptor op = (OperatorExpressionDescriptor) unary;
		assertNull(op.getLeftOperand());
		assertNotNull(op.getRightOperand());
		assertEquals(operator, op.getOperator());
		assertTrue(op.getRightOperand() instanceof NameExpressionDescriptor);
		assertEquals(var, ((NameExpressionDescriptor)op.getRightOperand()).getName());
	}
	
	public void testPostfixOperators() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 1);
		
		assertEquals(3, block.size());
		
		postfixTest((ExpressionDescriptor)block.get(0), "++");
		postfixTest((ExpressionDescriptor)block.get(1), "--");
	}
	
	private void postfixTest(ExpressionDescriptor postfix, String operator) {
		assertTrue(postfix instanceof OperatorExpressionDescriptor);
		
		OperatorExpressionDescriptor op = (OperatorExpressionDescriptor) postfix;
		assertNotNull(op.getLeftOperand());
		assertNull(op.getRightOperand());
		assertEquals(operator, op.getOperator());
		assertTrue(op.getLeftOperand() instanceof NameExpressionDescriptor);
		assertEquals("aaa", ((NameExpressionDescriptor)op.getLeftOperand()).getName());
	}
	
	public void testBinaryArifmeticOperators() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 2);
		
		assertEquals(12, block.size());
		
		binaryTest(((OperatorExpressionDescriptor)block.get(0)).getRightOperand(), "+");
		binaryTest(((OperatorExpressionDescriptor)block.get(1)).getRightOperand(), "-");
		binaryTest(((OperatorExpressionDescriptor)block.get(2)).getRightOperand(), "*");
		binaryTest(((OperatorExpressionDescriptor)block.get(3)).getRightOperand(), "/");
		binaryTest(((OperatorExpressionDescriptor)block.get(4)).getRightOperand(), "%");
		binaryTest(((OperatorExpressionDescriptor)block.get(5)).getRightOperand(), ">>");
		binaryTest(((OperatorExpressionDescriptor)block.get(6)).getRightOperand(), "<<");
		binaryTest(((OperatorExpressionDescriptor)block.get(7)).getRightOperand(), ">>>");
		binaryTest(((OperatorExpressionDescriptor)block.get(8)).getRightOperand(), "|");
		binaryTest(((OperatorExpressionDescriptor)block.get(9)).getRightOperand(), "&");
		binaryTest(((OperatorExpressionDescriptor)block.get(10)).getRightOperand(), "^");
	}

	private void binaryTest(ExpressionDescriptor binary, String operator) {
		assertTrue(binary instanceof OperatorExpressionDescriptor);
		
		OperatorExpressionDescriptor op = (OperatorExpressionDescriptor) binary;
		assertNotNull(op.getLeftOperand());
		assertNotNull(op.getRightOperand());
		assertEquals(operator, op.getOperator());
		
		assertTrue(op.getLeftOperand() instanceof NameExpressionDescriptor);
		assertEquals("aaa", ((NameExpressionDescriptor)op.getLeftOperand()).getName());
		
		assertTrue(op.getRightOperand() instanceof NameExpressionDescriptor);
		assertEquals("bbb", ((NameExpressionDescriptor)op.getRightOperand()).getName());
	}
	
	public void testBooleanOperators() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 3);
		
		assertEquals(3, block.size());
		
		binaryTest(((OperatorExpressionDescriptor)block.get(0)).getRightOperand(), "&&");
		binaryTest(((OperatorExpressionDescriptor)block.get(1)).getRightOperand(), "||");
	}
	
	public void testComparasion() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 4);
		
		assertEquals(8, block.size());
		
		binaryTest(((OperatorExpressionDescriptor)block.get(0)).getRightOperand(), ">");
		binaryTest(((OperatorExpressionDescriptor)block.get(1)).getRightOperand(), "<");
		binaryTest(((OperatorExpressionDescriptor)block.get(2)).getRightOperand(), ">=");
		binaryTest(((OperatorExpressionDescriptor)block.get(3)).getRightOperand(), "<=");
		binaryTest(((OperatorExpressionDescriptor)block.get(4)).getRightOperand(), "==");
		binaryTest(((OperatorExpressionDescriptor)block.get(5)).getRightOperand(), "!=");
		
		OperatorExpressionDescriptor binary = (OperatorExpressionDescriptor)((OperatorExpressionDescriptor)block.get(6)).getRightOperand();
		
		assertTrue(binary instanceof OperatorExpressionDescriptor);
		
		OperatorExpressionDescriptor op = (OperatorExpressionDescriptor) binary;
		assertNotNull(op.getLeftOperand());
		assertNotNull(op.getRightOperand());
		assertEquals("instanceof", op.getOperator());
		
		assertTrue(op.getLeftOperand() instanceof NameExpressionDescriptor);
		assertEquals("sss", ((NameExpressionDescriptor)op.getLeftOperand()).getName());
		
		assertTrue(op.getRightOperand() instanceof NameExpressionDescriptor);
		assertEquals("Integer", ((NameExpressionDescriptor)op.getRightOperand()).getName());
	}
	
	public void testAssignmentOperator() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 5);
		
		assertEquals(12, block.size());
		
		binaryTest((ExpressionDescriptor) block.get(0), "+=");
		binaryTest((ExpressionDescriptor) block.get(1), "/=");
		binaryTest((ExpressionDescriptor) block.get(2), "*=");
		binaryTest((ExpressionDescriptor) block.get(3), "-=");
		binaryTest((ExpressionDescriptor) block.get(4), "%=");
		binaryTest((ExpressionDescriptor) block.get(5), "^=");
		binaryTest((ExpressionDescriptor) block.get(6), "&=");
		binaryTest((ExpressionDescriptor) block.get(7), "|=");
		binaryTest((ExpressionDescriptor) block.get(8), ">>=");
		binaryTest((ExpressionDescriptor) block.get(9), ">>>=");
		binaryTest((ExpressionDescriptor) block.get(10), "<<=");
	}
	
	public void testDotOperator() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 6);
		
		Descriptor binary = block.get(0);
		
		assertTrue(binary instanceof OperatorExpressionDescriptor);
		
		OperatorExpressionDescriptor op = (OperatorExpressionDescriptor) binary;
		assertNotNull(op.getLeftOperand());
		assertNotNull(op.getRightOperand());
		assertEquals(".", op.getOperator());
		
		assertTrue(op.getLeftOperand() instanceof NameExpressionDescriptor);
		assertEquals("this", ((NameExpressionDescriptor)op.getLeftOperand()).getName());
		
		assertTrue(op.getRightOperand() instanceof OperatorExpressionDescriptor);
		
		op = (OperatorExpressionDescriptor) op.getRightOperand();
		assertNotNull(op.getLeftOperand());
		assertNotNull(op.getRightOperand());
		assertEquals("=", op.getOperator());
		
		assertTrue(op.getLeftOperand() instanceof NameExpressionDescriptor);
		assertEquals("data", ((NameExpressionDescriptor)op.getLeftOperand()).getName());
		
		assertTrue(op.getRightOperand() instanceof LiteralExpressionDescriptor);
		assertEquals(5, ((LiteralExpressionDescriptor)op.getRightOperand()).asInt());
	}
	
	public void testLiterals() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 6);
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(0)).getRightOperand(), 5);
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(1)).getRightOperand(), 10.0d);
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(2)).getRightOperand(), 5e-1f);
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(3)).getRightOperand(), 5l);
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(4)).getRightOperand(), '\u3214');
		assertLiteral((LiteralExpressionDescriptor) ((OperatorExpressionDescriptor)block.get(5)).getRightOperand(), "some string");
	}
	
	private void assertLiteral(LiteralExpressionDescriptor literal, Object obj) {
		assertNotNull(obj);
		assertNotNull(literal);
		assertEquals(literal.getType(), obj.getClass());
		
		if (obj instanceof String) {
			assertEquals(literal.asString(), obj);
		} else if (obj instanceof Character) {
			assertEquals(literal.asChar(), obj);
		} else if (obj instanceof Integer) {
			assertEquals(literal.asInt(), obj);
		} else if (obj instanceof Long) {
			assertEquals(literal.asLong(), obj);
		} else if (obj instanceof Double) {
			assertEquals(literal.asDouble(), obj);
		} else if (obj instanceof Float) {
			assertEquals(literal.asFloat(), obj);
		} else {
			fail();
		}
		
	}

	public void testTernaryOperator() throws PreprocessorException {
		BlockDescriptor block = getBlock(SimpleExpressionMock.class, 7);
		ExpressionDescriptor op = ((OperatorExpressionDescriptor)block.get(0)).getRightOperand();
		
		assertNotNull(op);
		assertTrue(op instanceof TernaryExpressionDescriptor);
		TernaryExpressionDescriptor ternary = (TernaryExpressionDescriptor) op;
		
		assertTrue(ternary.getCondition() instanceof NameExpressionDescriptor);
		assertTrue(ternary.getTrueExpression() instanceof NameExpressionDescriptor);
		assertTrue(ternary.getFalseExpression() instanceof NameExpressionDescriptor);
		
		assertEquals("aaa", ((NameExpressionDescriptor)ternary.getCondition()).getName());
		assertEquals("bbb", ((NameExpressionDescriptor)ternary.getTrueExpression()).getName());
		assertEquals("data", ((NameExpressionDescriptor)ternary.getFalseExpression()).getName());
	}
	
	public void testVariableDeclaration() {
		fail("Not implemented");
	}
	
	public void testNewOperator() {
		fail("Not implemented");
	}
	
	public void testCast() {
		fail("Not implemented");
	}
	
	public void testBrackets() {
		fail("Not implemented");
	}
	
	public void testMethodCall() {
		fail("Not implemented");
	}
	
	public void testComaOperator() {
		fail("Not implemented");
	}
	
	public void testComplex() {
		fail("Not implemented");
	}
	
	private BlockDescriptor getBlock(Class<?> clazz, int index) throws PreprocessorException {
		InputStream cu = getClass().getClassLoader().getResourceAsStream(Name.javaToFs(clazz.getCanonicalName()));
		try {
			JavaParser parser = JavaParser.create(cu);
			return parser.parse().getTopClasses().get(0).getMethods().get(index).getBody();
		} finally {
			try {
				cu.close();
			} catch(Exception ex) {
			}
		}
	}*/
}
